package com.itheima.reggie.aspect;

import com.itheima.reggie.aspect.annotation.OperLog;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.OperationLog;
import com.itheima.reggie.service.OperationLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.TimerTask;

@Slf4j
@Component   //被spring容器管理
@Aspect      //表明为：切面对象
public class OperationAspect {

    ///1.切入点表这式:标识哪些方法是切入点(需要进行增强的方法)
    @Pointcut("@annotation(com.itheima.reggie.aspect.annotation.OperLog)")  //使用该注解时增强
    private void operationMethod() {}


    @Autowired
    private OperationLogService operationLogService;

    ///3.切面:如间对哪些方法,进行哪些增强
    @Around("operationMethod()")
    // 2.通知:具体的增强代码
    public Object opertionLogHandle(ProceedingJoinPoint pjp) {

        OperationLog operationLog=new OperationLog();

        //获取目标方法
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        //获取目标方法上的注解
        OperLog annotation = method.getAnnotation(OperLog.class);
        //获取注解的属性
        String value = annotation.value();
        String useranme = annotation.useranme();
        String age = annotation.age();
        log.info("[AOP-增强测试]: value={},useranme={},age={}",value,useranme,age);


        operationLog.setOperation_action(value);
        operationLog.setUser_id(BaseContext.getCurrentId());
        //operationLog.setUser_id(ApplicationContext.getEmpId());

        //获取目标方法的参数：
        Object[] args = pjp.getArgs();

        Object result = null;
        try {
            //前置增强
            result = pjp.proceed(args);//执行目标方法
            //后置增强
        } catch (Throwable throwable) {
            //throwable.printStackTrace();
            //throw RuntimeException("");
            //异常增强
            //operationLogService.save(operationLog);
            new AsyncManager().execute(new TimerTask() {
                @Override
                public void run() {
                    operationLogService.save(operationLog);
                }
            });
        } finally {
            //返回值增强
            new AsyncManager().execute(new TimerTask() {
                @Override
                public void run() {
                    operationLogService.save(operationLog);
                }
            });
        }
        return result;
    }

    ///3.切面:如间对哪些方法,进行哪些增强
    //@Around("operationMethod()")
    // 2.通知:具体的增强代码
    public Object opertionLogHandle_init(ProceedingJoinPoint pjp) {

        //获取目标方法
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        //获取目标方法上的注解
        OperLog annotation = method.getAnnotation(OperLog.class);
        //获取注解的属性
        String value = annotation.value();
        String useranme = annotation.useranme();
        String age = annotation.age();
        log.info("[AOP-增强测试]: value={},useranme={},age={}",value,useranme,age);

        //获取目标方法的参数：
        Object[] args = pjp.getArgs();

        Object result = null;
        try {
            //前置增强
            result = pjp.proceed(args);//执行目标方法
            //后置增强
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            //异常增强
        } finally {
            //返回值增强
        }
        return result;
    }
}


//
